package com.sina.microblog.ut.cases
{
	import com.sina.microblog.MicroBlog;
	import com.sina.microblog.data.MicroBlogComment;
	import com.sina.microblog.data.MicroBlogCount;
	import com.sina.microblog.data.MicroBlogStatus;
	import com.sina.microblog.events.MicroBlogErrorEvent;
	import com.sina.microblog.events.MicroBlogEvent;
	import com.sina.microblog.ut.utils.ResultDataUtils;
	import com.sina.microblog.ut.utils.URLRequestChecker;
	import com.sina.microblog.ut.utils.URLRequestParameters;
	
	import flash.net.URLRequest;
	
	import flexunit.framework.Assert;
	
	import org.flexunit.asserts.assertNull;
	import org.flexunit.async.Async;
	import com.ut.nm_test_internal;
	
	use namespace nm_test_internal;
	[RunWith("org.flexunit.experimental.theories.Theories")]
	public class TimelineTest
	{
		
		
		private static const PUBLIC_TIMELINE_URL:String = "http://api.t.sina.com.cn/statuses/public_timeline.xml";
		private static const FRIENDS_TIMELINE_URL_BASE:String = "http://api.t.sina.com.cn/statuses/friends_timeline.xml";
		private static const USER_TIMELINE_URL_BASE:String = "http://api.t.sina.com.cn/statuses/user_timeline";
		private static const MENTIONS_URL_BASE:String = "http://api.t.sina.com.cn/statuses/mentions.xml";
		private static const COMMENTS_TIMELINE_URL_BASE:String = "http://api.t.sina.com.cn/statuses/comments_timeline.xml";
		private static const COMMENTS_BY_ME_URL_BASE:String = "http://api.t.sina.com.cn/statuses/comments_by_me.xml";
		private static const COMMENTS_URL_BASE:String = "http://api.t.sina.com.cn/statuses/comments.xml";
		private static const COUNTS_URL_BASE:String = "http://api.t.sina.com.cn/statuses/counts.xml";
		
		private static const TIME_OUT:uint = 500;	
		private static var mb:MicroBlog;
		
		
		[DataPoints]
		[ArrayElementType("uint")]
		public static var ids:Array = [0, 1, 201, 300];
		
		public function TimelineTest()
		{
			
		}
		[BeforeClass]
		public static function setUp():void
		{
			if ( null == mb )
			{
				mb = new MicroBlog();
			}
		}
		
		// Public timeline
		[Test(async,timeout="20000")]
		public function testPublicTimeline():void
		{
			Async.handleEvent(this, mb, MicroBlogEvent.LOAD_PUBLIC_TIMELINE_RESULT, this_onStatusArrayReturned, TIME_OUT);
			var params:URLRequestParameters = new URLRequestParameters(mb.source);
			var url:String = PUBLIC_TIMELINE_URL + params.toGetString();
			var req:URLRequest = new URLRequest(url);
			mb.loadPublicTimeline();
			URLRequestChecker.check(mb, req, ResultDataUtils.statusArray);
		}
		[Test(async,timeout="20000")]
		public function testPublicTimelineFail():void
		{
			Async.handleEvent(this, mb, MicroBlogErrorEvent.LOAD_PUBLIC_TIMELINE_ERROR, this_onErrorReturned, TIME_OUT);
			var params:URLRequestParameters = new URLRequestParameters(mb.source);
			var url:String = PUBLIC_TIMELINE_URL + params.toGetString();
			var req:URLRequest = new URLRequest(url);
			mb.loadPublicTimeline();
			URLRequestChecker.check(mb, req, ResultDataUtils.error);
			
			
		}
		
		//Friends timeline
		[Test(async,timeout="20000")]
		public function testFriendsTimelineWithoutParams():void
		{
			var params:URLRequestParameters = new URLRequestParameters(mb.source);
			var url:String = FRIENDS_TIMELINE_URL_BASE + params.toGetString();
			Async.handleEvent(this, mb, MicroBlogEvent.LOAD_FRIENDS_TIMELINE_RESULT, this_onStatusArrayReturned, TIME_OUT);
			
			var req:URLRequest = new URLRequest(url);
			mb.loadFriendsTimeline();
			URLRequestChecker.check(mb, req, ResultDataUtils.statusArray);			
			
		}
		[Test(async,timeout="20000")]
		public function testFriendsTimelineFail():void
		{
			var params:URLRequestParameters = new URLRequestParameters(mb.source);
			var url:String = FRIENDS_TIMELINE_URL_BASE + params.toGetString();
			Async.handleEvent(this, mb, MicroBlogErrorEvent.LOAD_FRIENDS_TIMELINE_ERROR, this_onErrorReturned, TIME_OUT);
			
			var req:URLRequest = new URLRequest(url);
			mb.loadFriendsTimeline();
			URLRequestChecker.check(mb, req, ResultDataUtils.error);			
			
		}
		[Theory]
		public function testFriendsTimeLineTheory(sinceID:uint, maxID:uint, count:uint, page:uint):void
		{	
			var params:URLRequestParameters = new URLRequestParameters(mb.source);
			params.makeQueryStr(sinceID, maxID, count, page);
			var url:String = FRIENDS_TIMELINE_URL_BASE + params.toGetString();
			var req:URLRequest = new URLRequest(url);
			mb.loadFriendsTimeline(sinceID, maxID, count, page);
			URLRequestChecker.check(mb, req, null);		
		}
		
		//User timeline
		[Test(async,timeout="20000")]
		public function testUserTimeline():void
		{
			var params:URLRequestParameters = new URLRequestParameters(mb.source);
			var url:String = USER_TIMELINE_URL_BASE+ "/test.xml" + params.toGetString();
			Async.handleEvent(this, mb, MicroBlogEvent.LOAD_USER_TIMELINE_RESULT, this_onStatusArrayReturned, TIME_OUT);
			
			var req:URLRequest = new URLRequest(url);
			mb.loadUserTimeline("test");
			URLRequestChecker.check(mb, req, ResultDataUtils.statusArray);			
			
		}
		[Test(async,timeout="20000")]
		public function testUserTimelineFail():void
		{
			var params:URLRequestParameters = new URLRequestParameters(mb.source);
			var url:String = USER_TIMELINE_URL_BASE+ "/test.xml" + params.toGetString();
			Async.handleEvent(this, mb, MicroBlogErrorEvent.LOAD_USER_TIMELINE_ERROR, this_onErrorReturned, TIME_OUT);
			
			var req:URLRequest = new URLRequest(url);
			mb.loadUserTimeline("test");
			URLRequestChecker.check(mb, req, ResultDataUtils.error);			
			
		}
		[Test(async,timeout="20000")]
		public function testUserTimelineWithNullUser():void
		{
			var params:URLRequestParameters = new URLRequestParameters(mb.source);
			var url:String = USER_TIMELINE_URL_BASE+ ".xml" + params.toGetString();
			Async.handleEvent(this, mb, MicroBlogEvent.LOAD_USER_TIMELINE_RESULT, this_onStatusArrayReturned, TIME_OUT);
			
			var req:URLRequest = new URLRequest(url);
			mb.loadUserTimeline(null);
			URLRequestChecker.check(mb, req, ResultDataUtils.statusArray);			
			
		}
		[Test(async,timeout="20000")]
		public function testUserTimelineWithEmptyUser():void
		{
			var params:URLRequestParameters = new URLRequestParameters(mb.source);
			var url:String = USER_TIMELINE_URL_BASE+ ".xml" + params.toGetString();
			Async.handleEvent(this, mb, MicroBlogEvent.LOAD_USER_TIMELINE_RESULT, this_onStatusArrayReturned, TIME_OUT);
			
			var req:URLRequest = new URLRequest(url);
			mb.loadUserTimeline("");
			URLRequestChecker.check(mb, req, ResultDataUtils.statusArray);			
			
		}
		[Theory]
		public function testUserTimeLineTheory(sinceID:uint, maxID:uint, count:uint, page:uint):void
		{	
			var params:URLRequestParameters = new URLRequestParameters(mb.source);
			params.makeQueryStr(sinceID, maxID, count, page);
			if ( sinceID > 0)
			{
				params.addParam("user_id", sinceID);
			}
			params.addParam("screen_name", "test");
			var url:String = USER_TIMELINE_URL_BASE+ "/test.xml" + params.toGetString();
			var req:URLRequest = new URLRequest(url);
			mb.loadUserTimeline("test",sinceID, "test", sinceID, maxID, count, page);
			URLRequestChecker.check(mb, req, null);		
		}
		
		//Mentions
		[Test(async,timeout="20000")]
		public function testMentions():void
		{
			var params:URLRequestParameters = new URLRequestParameters(mb.source);
			var url:String = MENTIONS_URL_BASE + params.toGetString();
			Async.handleEvent(this, mb, MicroBlogEvent.LOAD_MENSIONS_RESULT, this_onStatusArrayReturned, TIME_OUT);
			
			var req:URLRequest = new URLRequest(url);
			mb.loadMentions();
			URLRequestChecker.check(mb, req, ResultDataUtils.statusArray);			
			
		}
		[Test(async,timeout="20000")]
		public function testMentionsFail():void
		{
			var params:URLRequestParameters = new URLRequestParameters(mb.source);
			var url:String = MENTIONS_URL_BASE + params.toGetString();
			Async.handleEvent(this, mb, MicroBlogErrorEvent.LOAD_MENSIONS_ERROR, this_onErrorReturned, TIME_OUT);
			
			var req:URLRequest = new URLRequest(url);
			mb.loadMentions();
			URLRequestChecker.check(mb, req, ResultDataUtils.error);			
			
		}
		[Theory]
		public function testMentionsTheory(sinceID:uint, maxID:uint, count:uint, page:uint):void
		{	
			var params:URLRequestParameters = new URLRequestParameters(mb.source);
			params.makeQueryStr(sinceID, maxID, count, page);
			
			var url:String = MENTIONS_URL_BASE + params.toGetString();
			var req:URLRequest = new URLRequest(url);
			mb.loadMentions(sinceID, maxID, count, page);
			URLRequestChecker.check(mb, req, null);		
		}
		
		//Comments timeline
		[Test(async,timeout="20000")]
		public function testCommentsTimelineWithoutParams():void
		{
			var params:URLRequestParameters = new URLRequestParameters(mb.source);
			var url:String = COMMENTS_TIMELINE_URL_BASE + params.toGetString();
			Async.handleEvent(this, mb, MicroBlogEvent.LOAD_COMMENTS_TIMELINE_RESULT, this_onCommentsArrayReturned, TIME_OUT);
			
			var req:URLRequest = new URLRequest(url);
			mb.loadCommentsTimeline();
			URLRequestChecker.check(mb, req, ResultDataUtils.commentArray);			
			
		}
		[Test(async,timeout="20000")]
		public function testCommentsTimelineFail():void
		{
			var params:URLRequestParameters = new URLRequestParameters(mb.source);
			var url:String = COMMENTS_TIMELINE_URL_BASE + params.toGetString();
			Async.handleEvent(this, mb, MicroBlogErrorEvent.LOAD_COMMENTS_TIMELINE_ERROR, this_onErrorReturned, TIME_OUT);
			
			var req:URLRequest = new URLRequest(url);
			mb.loadCommentsTimeline();
			URLRequestChecker.check(mb, req, ResultDataUtils.error);			
			
		}
		[Theory]
		public function testCommentsTimeLineTheory(sinceID:uint, maxID:uint, count:uint, page:uint):void
		{	
			var params:URLRequestParameters = new URLRequestParameters(mb.source);
			params.makeQueryStr(sinceID, maxID, count, page);
			var url:String = COMMENTS_TIMELINE_URL_BASE + params.toGetString();
			var req:URLRequest = new URLRequest(url);
			mb.loadCommentsTimeline(sinceID, maxID, count, page);
			URLRequestChecker.check(mb, req, null);		
		}
		
		//Test MyComments.
		[Test(async,timeout="20000")]
		public function testCommentsByMeWithoutParams():void
		{
			var params:URLRequestParameters = new URLRequestParameters(mb.source);
			var url:String = COMMENTS_BY_ME_URL_BASE + params.toGetString();
			Async.handleEvent(this, mb, MicroBlogEvent.LOAD_MY_COMMENTS_RESULT, this_onCommentsArrayReturned, TIME_OUT);
			
			var req:URLRequest = new URLRequest(url);
			mb.loadMyComments();
			URLRequestChecker.check(mb, req, ResultDataUtils.commentArray);			
			
		}
		[Test(async,timeout="20000")]
		public function testCommentsByMeFail():void
		{
			var params:URLRequestParameters = new URLRequestParameters(mb.source);
			var url:String = COMMENTS_BY_ME_URL_BASE + params.toGetString();
			Async.handleEvent(this, mb, MicroBlogErrorEvent.LOAD_MY_COMMENTS_ERROR, this_onErrorReturned, TIME_OUT);
			
			var req:URLRequest = new URLRequest(url);
			mb.loadMyComments();
			URLRequestChecker.check(mb, req, ResultDataUtils.error);			
			
		}
		[Theory]
		public function testCommentsByMeTheory(sinceID:uint, maxID:uint, count:uint, page:uint):void
		{	
			var params:URLRequestParameters = new URLRequestParameters(mb.source);
			params.makeQueryStr(sinceID, maxID, count, page);
			var url:String = COMMENTS_BY_ME_URL_BASE + params.toGetString();
			var req:URLRequest = new URLRequest(url);
			mb.loadMyComments(sinceID, maxID, count, page);
			URLRequestChecker.check(mb, req, null);		
		}
		
		//Test MyComments.
		[Test(async,timeout="20000")]
		public function testCommentsWithoutParams():void
		{
			var params:URLRequestParameters = new URLRequestParameters(mb.source);
			params.addParam("id", 168890);
			var url:String =COMMENTS_URL_BASE + params.toGetString();
			Async.handleEvent(this, mb, MicroBlogEvent.LOAD_COMMENTS_RESULT, this_onCommentsArrayReturned, TIME_OUT);
			
			var req:URLRequest = new URLRequest(url);
			mb.loadCommentList(168890);
			URLRequestChecker.check(mb, req, ResultDataUtils.commentArray);			
			
		}
		[Test(async,timeout="20000")]
		public function testCommentsFail():void
		{
			var params:URLRequestParameters = new URLRequestParameters(mb.source);
			params.addParam("id", 168890);
			var url:String =COMMENTS_URL_BASE + params.toGetString();
			Async.handleEvent(this, mb, MicroBlogErrorEvent.LOAD_COMMENTS_ERROR, this_onErrorReturned, TIME_OUT);
			
			var req:URLRequest = new URLRequest(url);
			mb.loadCommentList(168890);
			URLRequestChecker.check(mb, req, ResultDataUtils.error);			
			
		}
		[Theory]
		public function testCommentsTheory(id:uint, count:uint, page:uint):void
		{	
			var params:URLRequestParameters = new URLRequestParameters(mb.source);
			
			params.addParam("id", id);
			
			if ( count > 0)
			{
				params.addParam("count", count);
			}
			if ( page > 0 )
			{
				params.addParam("page", page);
			}
			var url:String = COMMENTS_URL_BASE + params.toGetString();
			var req:URLRequest = new URLRequest(url);
			mb.loadCommentList(id, count, page);
			URLRequestChecker.check(mb, req, null);		
		}
		
		//Test Counts.
		[Test(async,timeout="20000")]
		public function testCounts():void
		{
			var ids:Array = [1,233,4555,64545];
			var idStr:String = ids.join(",");
			var params:URLRequestParameters = new URLRequestParameters(mb.source);
			params.addParam("ids", idStr);
			var url:String =COUNTS_URL_BASE + params.toGetString();
			Async.handleEvent(this, mb, MicroBlogEvent.LOAD_STATUS_COUNTS_RESULT, this_onCountsReturned, TIME_OUT);
			
			var req:URLRequest = new URLRequest(url);
			mb.loadStatusCounts(ids);
			URLRequestChecker.check(mb, req, ResultDataUtils.counts);			
			
		}
		[Test(async,timeout="20000")]
		public function testCountsFail():void
		{
			var ids:Array = [1,233,4555,64545];
			var idStr:String = ids.join(",");
			var params:URLRequestParameters = new URLRequestParameters(mb.source);
			params.addParam("ids", idStr);
			var url:String =COUNTS_URL_BASE + params.toGetString();
			Async.handleEvent(this, mb, MicroBlogErrorEvent.LOAD_STATUS_COUNTS_ERROR, this_onErrorReturned, TIME_OUT);
			
			var req:URLRequest = new URLRequest(url);
			mb.loadStatusCounts(ids);
			URLRequestChecker.check(mb, req, ResultDataUtils.error);			
			
		}
		[Test]
		public function testCountsWithEmptyIDs():void
		{
			mb.lastRequest = null;
			mb.loadStatusCounts(null);
			assertNull(mb.lastRequest);
			var ids:Array = [];
			mb.loadStatusCounts(ids);
			assertNull(mb.lastRequest);
			
		}
		private function this_onStatusArrayReturned(event:MicroBlogEvent, params:Object):void
		{
			var statusArray:Array = event.result as Array;
			Assert.assertNotNull(statusArray);
			Assert.assertTrue((statusArray.length > 0 && statusArray.length < 21) );
			Assert.assertTrue( statusArray[0] is MicroBlogStatus );
		}
		private function this_onCountsReturned(event:MicroBlogEvent, params:Object):void
		{
			var countArray:Array = event.result as Array;
			Assert.assertNotNull(countArray);
			Assert.assertTrue(countArray.length > 0);
			Assert.assertTrue(countArray[0] is MicroBlogCount);
		}
		private function this_onErrorReturned(event:MicroBlogErrorEvent, params:Object):void
		{
			Assert.assertTrue(true);
		}
		
		private function this_onCommentsArrayReturned(event:MicroBlogEvent, params:Object):void
		{
			var cArray:Array = event.result as Array;
			Assert.assertNotNull(cArray);
			Assert.assertTrue((cArray.length > 0 && cArray.length < 21) );
			Assert.assertTrue( cArray[0] is MicroBlogComment );
		}
		
	}
}